package com.spider.moudle.api.realize;

import com.google.common.collect.Lists;
import com.spider.moudle.api.LoginDownloader;
import com.spider.moudle.entity.Cookie;
import com.spider.moudle.entity.ResponseEntity;
import com.spider.moudle.factory.DownloaderFactory;
import com.spider.moudle.factory.HttpClientFactory;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 夏茂轩
 * @description 下载器，非线程安全
 * @date 2017/12/8 15:26
 */
public class StandardLoginDownloader implements LoginDownloader {
    private ArrayList<Cookie> cookies = null;
    private List<Header> headers = Lists.newArrayList();
    private String encoding;

    @Override
    public ResponseEntity get(String url) throws Exception {
        ResponseEntity responseEntity = null;
        CloseableHttpClient httpClient = null;
        httpClient = HttpClientFactory.buildHttpClient(false);
        HttpUriRequest request = DownloaderFactory.buildRequest(url, "get", null, HttpClientFactory.buildRequestConfig(null), this.headers, this.encoding);
        responseEntity = DownloaderFactory.execute(request, httpClient, null, this.encoding);
        return responseEntity;
    }

    @Override
    public ResponseEntity post(String url) throws Exception {
        ResponseEntity responseEntity = null;
        CloseableHttpClient httpClient = null;
        httpClient = HttpClientFactory.buildHttpClient(false);
        HttpUriRequest request = DownloaderFactory.buildRequest(url, "post", null, HttpClientFactory.buildRequestConfig(null), this.headers, this.encoding);
        responseEntity = DownloaderFactory.execute(request, httpClient, null, this.encoding);
        return responseEntity;
    }

    @Override
    public ResponseEntity post(String url, Map<String, String> params) throws Exception {
        ResponseEntity responseEntity = null;
        CloseableHttpClient httpClient = null;
        httpClient = HttpClientFactory.buildHttpClient(false);
        HttpUriRequest request = DownloaderFactory.buildRequest(url, "post", params, HttpClientFactory.buildRequestConfig(null), this.headers, this.encoding);
        responseEntity = DownloaderFactory.execute(request, httpClient, null, this.encoding);
        return responseEntity;
    }

    @Override
    public void addHeader(String name, String val) {
        synchronized (headers) {
            Header header = new BasicHeader(name, val);
            headers.add(header);
        }
    }

    public List<Cookie> getCookies() {
        return cookies;
    }

    private void handleAfter(CloseableHttpResponse response, InputStream inputStream) throws Exception {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw e;
            }
        }
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                throw e;
            }
        }
    }

    private ArrayList<Header> headerTranslate(Header[] headers) {
        ArrayList<Header> x = Arrays.asList(headers).stream().collect(Collectors.toCollection(ArrayList::new));
        return x;
    }

    public StandardLoginDownloader(ArrayList<Cookie> cookies, List<Header> headers, String encoding) {
        this.cookies = cookies;
        this.headers = headers;
        this.encoding = encoding;
        refreshCookie();
    }

    public StandardLoginDownloader(ArrayList<Cookie> cookies) {
        this.cookies = cookies;
        refreshCookie();
    }

    public StandardLoginDownloader(ArrayList<Cookie> cookies, List<Header> headers) {
        this.cookies = cookies;
        this.headers = headers;
        refreshCookie();
    }

    public StandardLoginDownloader(ArrayList<Cookie> cookies, String encoding) {
        this.cookies = cookies;
        this.encoding = encoding;
        refreshCookie();
    }

    private void refreshCookie() {
        String cookies = Cookie.toCookieString(this.cookies);
        this.headers.add(new BasicHeader("Cookie", cookies));
    }
    /* @Override
    protected StandardLoginDownloader clone() throws CloneNotSupportedException {
        ArrayList<Cookie> c = (ArrayList<Cookie>) ((ArrayList<Cookie>) cookies).clone();
        ArrayList<Header> h = (ArrayList<Header>) ((ArrayList<Header>) headers).clone();
        return new StandardLoginDownloader(c, new String(encoding), h);
    }*/
}
